package com.flyco.modules.stm.controller;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.flyco.common.api.vo.Result;
import com.flyco.common.aspect.annotation.AutoLog;
import com.flyco.common.system.query.QueryGenerator;
import com.flyco.common.system.vo.LoginUser;
import com.flyco.common.util.oConvertUtils;
import com.flyco.modules.oms.entity.OmsOrder;
import com.flyco.modules.oms.entity.OmsOrderInvoice;
import com.flyco.modules.oms.entity.OmsOrderItem;
import com.flyco.modules.oms.entity.OmsOrderTrace;
import com.flyco.modules.oms.model.OmsOrderModel;
import com.flyco.modules.oms.vo.OmsOrderItemPage;
import com.flyco.modules.stm.entity.StmStoreInfo;
import com.flyco.modules.stm.service.*;
import com.flyco.modules.oms.vo.OmsOrderPage;
import com.flyco.modules.system.service.ISysDictService;
import com.flyco.poi.excel.ExcelImportUtil;
import com.flyco.poi.excel.def.NormalExcelConstants;
import com.flyco.poi.excel.entity.ExportParams;
import com.flyco.poi.excel.entity.ImportParams;
import com.flyco.poi.excel.view.EntityExcelView;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description: 订单管理
 * @Author: flyco
 * @Date:   2019-12-10
 * @Version: V1.0
 */
@Api(tags = "门店订单")
@RestController
@RequestMapping("/f/stm/omsOrder")
@Slf4j
public class StmOrderController {
	@Autowired
	private IStmOrderService omsOrderService;
	@Autowired
	private IStmOrderItemService omsOrderItemService;
	@Autowired
	private IStmOrderInvoiceService omsOrderInvoiceService;
	@Autowired
	private ISysDictService dictService;
	@Autowired
	private IStmOrderTraceService omsOrderTraceService;
	@Autowired
	private IStmStoreInfoService stmStoreInfoService;
	
	/**
	 * 分页列表查询
	 *
	 * @param omsOrder
	 * @param pageNo
	 * @param pageSize
	 * @param req
	 * @return
	 */
	@AutoLog(value = "门店订单-分页列表查询")
	@ApiOperation(value="门店订单-分页列表查询", notes="门店订单-分页列表查询")
	@GetMapping(value = "/list")
	public Result<?> queryPageList(OmsOrder omsOrder,
								   @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
								   @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
								   HttpServletRequest req) {
		QueryWrapper<OmsOrder> queryWrapper = QueryGenerator.initQueryWrapper(omsOrder, req.getParameterMap());
		queryWrapper.orderByDesc("id");
		Page<OmsOrder> page = new Page<OmsOrder>(pageNo, pageSize);
		IPage<OmsOrder> pageList = omsOrderService.page(page, queryWrapper);
		if (pageList.getTotal() > 0) {
			List<StmStoreInfo> storeInfos = stmStoreInfoService.list();
			Map<Long, String> storeInfoMaps = storeInfos.stream().collect(Collectors.toMap(StmStoreInfo::getStoreId, StmStoreInfo::getName, (key1, key2) -> key2));
			pageList.getRecords().forEach(stock -> {
				if (oConvertUtils.isNotEmpty(stock.getStoreId())) {
					if (storeInfoMaps.containsKey(stock.getStoreId())) {
						stock.setStoreId_dictText(storeInfoMaps.get(stock.getStoreId()));
					} else {
						if (Objects.equals(0L , stock.getStoreId() )) {
							stock.setStoreId_dictText("线上商城");
						}
					}
				}
			});
		}
		return Result.ok(pageList);
	}


	/**
	 * 分页列表查询
	 *
	 * @param omsOrder
	 * @param pageNo
	 * @param pageSize
	 * @param req
	 * @return
	 */
	@AutoLog(value = "门店订单-分页列表查询")
	@ApiOperation(value="门店订单-分页列表查询", notes="门店订单-分页列表查询")
	@GetMapping(value = "/listWithItem")
	public Result<?> queryPageListWithItem(OmsOrder omsOrder,
								   @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
								   @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
								   HttpServletRequest req) {
		QueryWrapper<OmsOrder> queryWrapper = QueryGenerator.initQueryWrapper(omsOrder, req.getParameterMap());
		Map<String, String[]> parameterMap = req.getParameterMap();
		String productSn = null;
		if (oConvertUtils.isNotEmpty(parameterMap) && parameterMap.containsKey("productSn")) {
			productSn = parameterMap.get("productSn")[0].trim();
		}
		queryWrapper.orderByDesc("id");
		Page<OmsOrder> page = new Page<OmsOrder>(pageNo, pageSize);
		IPage<OmsOrder> pageList = omsOrderService.getOrderPage(page, queryWrapper, productSn);

        Page<OmsOrderPage> orderPage = new Page<OmsOrderPage>(pageNo, pageSize);
        List<OmsOrderPage> orderPages = new ArrayList<OmsOrderPage>();

		if (pageList.getTotal() > 0) {
			List<StmStoreInfo> storeInfos = stmStoreInfoService.list();
			Map<Long, String> storeInfoMaps = storeInfos.stream().collect(Collectors.toMap(StmStoreInfo::getStoreId, StmStoreInfo::getName, (key1, key2) -> key2));
			pageList.getRecords().forEach(order -> {
				if (oConvertUtils.isNotEmpty(order.getStoreId())) {
					if (storeInfoMaps.containsKey(order.getStoreId())) {
                        order.setStoreId_dictText(storeInfoMaps.get(order.getStoreId()));
					} else {
						if (Objects.equals(0L , order.getStoreId() )) {
                            order.setStoreId_dictText("线上商城");
						}
					}
				}
                OmsOrderPage omsOrderPage = BeanUtils.instantiateClass(OmsOrderPage.class);
                BeanUtils.copyProperties(order, omsOrderPage);
                List<OmsOrderItem> omsOrderItemList = omsOrderItemService.selectByMainId(order.getId());
                omsOrderPage.setOmsOrderItemList(omsOrderItemList);
                //List<OmsOrderInvoice> omsOrderInvoiceList = omsOrderInvoiceService.selectByMainId(temp.getId());
                //vo.setOmsOrderInvoiceList(omsOrderInvoiceList);
                orderPages.add(omsOrderPage);
            });
		}
        IPage<OmsOrderPage> orderPageList = orderPage.setRecords(orderPages);
		orderPageList.setTotal(pageList.getTotal());



        /*Page<OmsOrderItemPage> orderItemPage = new Page<OmsOrderItemPage>(pageNo, pageSize);
        List<OmsOrderItemPage> orderItemPages = new ArrayList<OmsOrderItemPage>();
        if (pageList.getTotal() > 0) {
            List<StmStoreInfo> storeInfos = stmStoreInfoService.list();
            Map<Long, String> storeInfoMaps = storeInfos.stream().collect(Collectors.toMap(StmStoreInfo::getStoreId, StmStoreInfo::getName, (key1, key2) -> key2));
            pageList.getRecords().forEach(order -> {
                if (oConvertUtils.isNotEmpty(order.getStoreId())) {
                    if (storeInfoMaps.containsKey(order.getStoreId())) {
                        order.setStoreId_dictText(storeInfoMaps.get(order.getStoreId()));
                    } else {
                        if (Objects.equals(0L , order.getStoreId() )) {
                            order.setStoreId_dictText("线上商城");
                        }
                    }
                }
                List<OmsOrderItem> omsOrderItemList = omsOrderItemService.selectByMainId(order.getId());
                omsOrderItemList.forEach(item->{
                    OmsOrderItemPage omsOrderItemPage = BeanUtils.instantiateClass(OmsOrderItemPage.class);
                    omsOrderItemPage.setByOreder(order);
                    omsOrderItemPage.setByOrderItem(item);
                    orderItemPages.add(omsOrderItemPage);
                });
            });
        }
        IPage<OmsOrderItemPage> orderPageList = orderItemPage.setRecords(orderItemPages);*/


		return Result.ok(orderPageList);
	}


	/**
	 * 改价
	 *
	 * @param orderVO
	 * @return
	 */
	@AutoLog(value = "订单-改价")
	@PutMapping(value = "/editiItemPrice")
	public Result<?> editiItemPrice(@RequestBody OmsOrderModel orderVO) {
		if (null != orderVO.getOrderId() && null != orderVO.getMap()) {
			OmsOrder order = omsOrderService.getById(orderVO.getOrderId());
			if (null == order || 7 != order.getStatus()) return Result.error("当前状态不可修改价格");
			OmsOrder changeOrder = new OmsOrder();
			//changeOrder.setId(order.getId());
			Map<Long, BigDecimal> applyMap = orderVO.getMap();
			List<OmsOrderItem> items = omsOrderItemService.selectByMainId(orderVO.getOrderId());
			List<OmsOrderItem> changeItems = new ArrayList<>();
			BigDecimal promotionAmount = new BigDecimal("0");
			for (OmsOrderItem orderItem : items) {
				BigDecimal itemPromotionAmount = (orderItem.getPromotionAmount() == null ? BigDecimal.ZERO : orderItem.getPromotionAmount());
				if (applyMap.containsKey(orderItem.getId())) {
					if (!"0".equals(orderItem.getOrderProductType())) return Result.error("非普通商品的价格不可以修改");
					OmsOrderItem changeItem = new OmsOrderItem();
					changeItem.setId(orderItem.getId());

					log.info("ItemID:{},product_price:{},promotion_amount:{},total_real_amount:{}", orderItem.getId(), orderItem.getProductPrice(), orderItem.getPromotionAmount(), orderItem.getTotalRealAmount());
					BigDecimal applyPrice = applyMap.get(orderItem.getId());//申请价格
					BigDecimal changePrice = orderItem.getProductPrice().subtract(applyPrice);//需要改的数量
					log.info("applyPrice:{},changePrice{}", applyPrice, changePrice);
					changeItem.setPromotionAmount(changePrice);
					changeItem.setTotalPromotionAmount(changeItem.getPromotionAmount().multiply(new BigDecimal(orderItem.getProductQuantity())));
					itemPromotionAmount = changeItem.getPromotionAmount();
					changeItem.setPromotionName("后台改价优惠：" + changePrice);
					//原价-促销优惠-优惠券抵扣-积分抵扣
					BigDecimal realAmount = orderItem.getProductPrice()
							.subtract(changeItem.getPromotionAmount())
							.subtract(orderItem.getCouponAmount())
							.subtract(orderItem.getIntegrationAmount());
					changeItem.setRealAmount(realAmount);
					//顺便计算小计金额
					BigDecimal totalRealAmount = orderItem.getProductPrice().multiply(new BigDecimal(orderItem.getProductQuantity()))
							.subtract(changeItem.getPromotionAmount().multiply(new BigDecimal(orderItem.getProductQuantity())))
							.subtract(orderItem.getTotalCouponAmount() == null ? BigDecimal.ZERO : orderItem.getTotalCouponAmount())
							.subtract(orderItem.getTotalIntegrationAmount() == null ? BigDecimal.ZERO : orderItem.getTotalIntegrationAmount());

					changeItem.setTotalRealAmount(totalRealAmount);
					changeItems.add(changeItem);
				}
				promotionAmount = promotionAmount.add(itemPromotionAmount.multiply(new BigDecimal(orderItem.getProductQuantity())));
			}
			changeOrder.setPromotionAmount(promotionAmount);
			changeOrder.setPayAmount(order.getTotalAmount().add(order.getFreightAmount() == null ? BigDecimal.ZERO : order.getFreightAmount()).subtract(changeOrder.getPromotionAmount()).subtract(order.getCouponAmount() == null ? BigDecimal.ZERO : order.getCouponAmount()).subtract(order.getIntegrationAmount() == null ? BigDecimal.ZERO : order.getIntegrationAmount()));
			changeOrder.setEffectiveAmount(changeOrder.getPayAmount());
			LambdaQueryWrapper<OmsOrder> query = new LambdaQueryWrapper<>();
			query.eq(OmsOrder::getId, order.getId());
			query.in(OmsOrder::getStatus, Arrays.asList(0));
			query.in(OmsOrder::getPayStatus, Arrays.asList(2));

			omsOrderService.update(changeOrder, query);
			omsOrderItemService.updateBatchById(changeItems);
			return Result.ok("修改价格成功!");
		}
		return Result.error("修改价格失败!");
	}


	
	/**
	 * 通过id查询
     *
	 * @param id
	 * @return
	 */
	@GetMapping(value = "/queryById")
	public Result<?> queryById(@RequestParam(name="id",required=true) String id) {
		OmsOrder omsOrder = omsOrderService.getById(id);
		return Result.ok(omsOrder);
	}
	
	/**
	 * 通过id查询商品信息
     *
	 * @param id
	 * @return
	 */
	@GetMapping(value = "/queryOmsOrderItemByMainId")
	public Result<?> queryOmsOrderItemListByMainId(@RequestParam(name="id",required=true) String id) {
        List<OmsOrderItem> items =  omsOrderItemService.selectByMainId(id);
        for ( OmsOrderItem item : items ) {
        	if(!StringUtils.isEmpty(item.getOrderProductType()))
				item.setOrderProductType_dictText(dictService.queryDictTextByKey("order_product_type",item.getOrderProductType()));
		}
		return Result.ok(items);
	}
	/**
	 * 通过id查询发票信息
     *
	 * @param id
	 * @return
	 */
	@GetMapping(value = "/queryOmsOrderInvoiceByMainId")
	public Result<?> queryOmsOrderInvoiceListByMainId(@RequestParam(name="id",required=true) String id) {
        List<OmsOrderInvoice> invoices =  omsOrderInvoiceService.selectByMainId(id);
        for ( OmsOrderInvoice invoice : invoices ) {
			if(!StringUtils.isEmpty(invoice.getInvoiceType()))
				invoice.setInvoiceType_dictText(dictService.queryDictTextByKey("invoice_type",invoice.getInvoiceType()));
			if(!StringUtils.isEmpty(invoice.getInvoiceStatus()))
				invoice.setInvoiceStatus_dictText(dictService.queryDictTextByKey("invoice_status",invoice.getInvoiceStatus().toString()));
			if(!StringUtils.isEmpty(invoice.getDeleteStatus()))
				invoice.setDeleteStatus_dictText(dictService.queryDictTextByKey("yn",invoice.getDeleteStatus().toString()));
		}
		return Result.ok(invoices);
	}

	/**
	 * 查询订单跟踪信息
	 *
	 * @param id
	 * @return
	 */
	@AutoLog(value = "门店订单-查询订单跟踪信息")
	@GetMapping(value = "/queryOmsOrderTrace")
	public Result<?> queryOmsOrderTrace(@RequestParam(name="id",required=true) String id) {
		OmsOrder omsOrder = omsOrderService.getById(id);
		if(null == omsOrder) return Result.error("查询的订单不存在");
		LambdaQueryWrapper<OmsOrderTrace> query = new LambdaQueryWrapper<>();
		query.eq(OmsOrderTrace::getOrderId,id);
		if (oConvertUtils.isNotEmpty(omsOrder.getDeliverySn())) {
			query.or();
			query.eq(OmsOrderTrace::getTraceNo,omsOrder.getDeliverySn());
		}
		query.orderByDesc(OmsOrderTrace::getCreateTime);
		List<OmsOrderTrace> traceList = omsOrderTraceService.list(query);
		return Result.ok(traceList);
	}

  /**
   * 导出excel
   *
   * @param request
   * @param omsOrder
   */
  @RequestMapping(value = "/exportXls")
  public ModelAndView exportXls(HttpServletRequest request, OmsOrder omsOrder) {
      // Step.1 组装查询条件
      QueryWrapper<OmsOrder> queryWrapper = QueryGenerator.initQueryWrapper(omsOrder, request.getParameterMap());
      LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();

      //要么导出选中的，要么空
      String selections = request.getParameter("selections");
      if (oConvertUtils.isNotEmpty(selections)) {
          List<String> selectionList = Arrays.asList(selections.split(","));
          queryWrapper.in("id",selectionList);
      } else {
          queryWrapper.in("id",0);
      }

      //Step.2 获取导出数据
      List<OmsOrderPage> pageList = new ArrayList<OmsOrderPage>();
      List<OmsOrder> omsOrderList = omsOrderService.list(queryWrapper);

	  List<StmStoreInfo> storeInfos = stmStoreInfoService.list();
	  Map<Long, String> storeInfoMaps = storeInfos.stream().collect(Collectors.toMap(StmStoreInfo::getStoreId, StmStoreInfo::getName, (key1, key2) -> key2));

	  for (OmsOrder temp : omsOrderList) {
		  if (storeInfoMaps.containsKey(temp.getStoreId())) {
			  temp.setStoreId_dictText(storeInfoMaps.get(temp.getStoreId()));
		  }
          OmsOrderPage vo = new OmsOrderPage();
          BeanUtils.copyProperties(temp, vo);
          List<OmsOrderItem> omsOrderItemList = omsOrderItemService.selectByMainId(temp.getId());
          vo.setOmsOrderItemList(omsOrderItemList);
          List<OmsOrderInvoice> omsOrderInvoiceList = omsOrderInvoiceService.selectByMainId(temp.getId());
          vo.setOmsOrderInvoiceList(omsOrderInvoiceList);
          pageList.add(vo);
      }
      //Step.3 调用AutoPoi导出Excel
      ModelAndView mv = new ModelAndView(new EntityExcelView());
      mv.addObject(NormalExcelConstants.FILE_NAME, "门店订单管理");
      mv.addObject(NormalExcelConstants.CLASS, OmsOrderPage.class);
      mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("门店订单管理数据", "导出人:"+sysUser.getRealname(), "订单管理"));
      mv.addObject(NormalExcelConstants.DATA_LIST, pageList);
      return mv;
  }


	/**
	 * 导出excel
	 *
	 * @param request
	 * @param omsOrder
	 */
	@RequestMapping(value = "/exportXlsForFinance")
	public ModelAndView exportXlsForFinance(HttpServletRequest request, OmsOrder omsOrder) {
		// Step.1 组装查询条件
		QueryWrapper<OmsOrder> queryWrapper = QueryGenerator.initQueryWrapper(omsOrder, request.getParameterMap());
		LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();

		//要么导出选中的，要么空
		String selections = request.getParameter("selections");
		if (oConvertUtils.isNotEmpty(selections)) {
			List<String> selectionList = Arrays.asList(selections.split(","));
			queryWrapper.in("id",selectionList);
		}

		//Step.2 获取导出数据
		List<OmsOrderPage> pageList = new ArrayList<OmsOrderPage>();
		List<OmsOrder> omsOrderList = omsOrderService.list(queryWrapper);

		List<StmStoreInfo> storeInfos = stmStoreInfoService.list();
		Map<Long, String> storeInfoMaps = storeInfos.stream().collect(Collectors.toMap(StmStoreInfo::getStoreId, StmStoreInfo::getName, (key1, key2) -> key2));

		for (OmsOrder temp : omsOrderList) {
			if (storeInfoMaps.containsKey(temp.getStoreId())) {
				temp.setStoreId_dictText(storeInfoMaps.get(temp.getStoreId()));
			}
			OmsOrderPage vo = new OmsOrderPage();
			BeanUtils.copyProperties(temp, vo);
			List<OmsOrderItem> omsOrderItemList = omsOrderItemService.selectByMainId(temp.getId());
			vo.setOmsOrderItemList(omsOrderItemList);
			List<OmsOrderInvoice> omsOrderInvoiceList = omsOrderInvoiceService.selectByMainId(temp.getId());
			vo.setOmsOrderInvoiceList(omsOrderInvoiceList);
			pageList.add(vo);
		}
		//Step.3 调用AutoPoi导出Excel
		ModelAndView mv = new ModelAndView(new EntityExcelView());
		mv.addObject(NormalExcelConstants.FILE_NAME, "门店订单管理");
		mv.addObject(NormalExcelConstants.CLASS, OmsOrderPage.class);
		mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("门店订单管理数据", "导出人:"+sysUser.getRealname(), "订单管理"));
		mv.addObject(NormalExcelConstants.DATA_LIST, pageList);
		return mv;
	}

  /**
   * 通过excel导入数据
   *
   * @param request
   * @param response
   * @return
   */
  @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
  public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
      return Result.ok("文件导入失败！");
  }

}
